package cn.example.demo.modules.house.service.impl;

import cn.example.demo.common.db.pojo.entity.BaseEntity;
import cn.example.demo.common.model.service.ServiceResult;
import cn.example.demo.common.retrieval.PageBean;
import cn.example.demo.common.secure.annotation.DataScopeEnable;
import cn.example.demo.common.secure.context.LoginUserApi;
import cn.example.demo.common.tools.QueryServiceUtils;
import cn.example.demo.common.tools.obj.reflect.EntityUtils;
import cn.example.demo.modules.house.dto.RecommendResultDto;
import cn.example.demo.modules.house.entity.RecommendResult;
import cn.example.demo.modules.house.mapper.RecommendResultMapper;
import cn.example.demo.modules.house.service.IRecommendResultService;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * 描述：【推荐结果】接口实现类
 */
@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
@Service
public class RecommendResultServiceImpl extends ServiceImpl<RecommendResultMapper, RecommendResult> implements IRecommendResultService {
    @Autowired
    private LoginUserApi loginUserApi;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult insertRecommendResult(RecommendResultDto recommendResultDto) {
        RecommendResult entity = EntityUtils.entityConvert(recommendResultDto, new RecommendResult(), false);

        if (this.save(entity)) {
            return ServiceResult.isSuccess(StrUtil.format("【推荐结果，ID:{}】创建成功!", entity.getId()), entity);
        }

        return ServiceResult.isInternalError("【推荐结果】创建失败，未知错误！");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult updateRecommendResult(RecommendResultDto recommendResultDto) {
        RecommendResult entity = this.getById(recommendResultDto.getId());
        if (entity == null) {
            return ServiceResult.isNotFound(StrUtil.format("【推荐结果】信息更新失败：记录不存在！ID:{}", recommendResultDto.getId()));
        }

        entity = EntityUtils.entityConvert(recommendResultDto, entity, true);
        if (this.updateById(entity)) {
            return ServiceResult.isSuccess(StrUtil.format("【推荐结果，ID:{}】信息更新成功!", entity.getId()), null);
        }

        return ServiceResult.isNotModified("未知错误，【推荐结果】信息修改失败！");
    }

    @Override
    public PageBean<RecommendResult> queryRecommendResult(RecommendResultDto recommendResultDto) {
        Page<RecommendResult> pageResult = PageHelper.startPage(recommendResultDto.getPageNum(), recommendResultDto.getPageSize())
                .doSelectPage(() -> this.list(getQueryWrapper(recommendResultDto)));
        return QueryServiceUtils.encapsulatePageBean(new PageBean<>(), pageResult);
    }

    @Override
    public RecommendResult queryRecommendResultByUserId(Integer userId) {
        List<RecommendResult> results = this.baseMapper.selectList(new LambdaQueryWrapper<RecommendResult>().eq(RecommendResult::getUserId, userId).orderByDesc(BaseEntity::getCreateTime));
        return results.isEmpty() ? null : results.get(0);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult deleteRecommendResult(RecommendResultDto recommendResultDto) {
        int rows = this.baseMapper.deleteBatchIds(recommendResultDto.getIds());
        if (rows > 0) {
            return ServiceResult.isSuccess(StrUtil.format("操作成功，已批量删除【推荐结果】共 {} 条记录！", rows), rows);
        }

        return ServiceResult.isNotModified("删除【推荐结果】失败，请稍后重试！");
    }

    @Override
    public RecommendResult findRecommendResultById(String id) {
        return this.getById(id);
    }

    @Override
    public List<Map<String, Object>> queryRecommendResultAsDict(RecommendResultDto recommendResultDto) {
        return this.baseMapper.selectAsDictList(getQueryWrapper(recommendResultDto));
    }

    /**
     * 查询条件
     *
     * @param recommendResultDto
     * @return
     */
    @DataScopeEnable
    protected LambdaQueryWrapper getQueryWrapper(RecommendResultDto recommendResultDto) {
        LambdaQueryWrapper<RecommendResult> wrapper = Wrappers.lambdaQuery();

        wrapper
                .eq(recommendResultDto.getId() != null, RecommendResult::getId, recommendResultDto.getId())

                .eq(recommendResultDto.getUserId() != null, RecommendResult::getUserId, recommendResultDto.getUserId())

                .eq(recommendResultDto.getRecommendedIds() != null, RecommendResult::getRecommendedIds, recommendResultDto.getRecommendedIds())

                .like(StrUtil.isNotBlank(recommendResultDto.getAlgorithmVersion()), RecommendResult::getAlgorithmVersion, recommendResultDto.getAlgorithmVersion())

                .like(StrUtil.isNotBlank(recommendResultDto.getGenerateStrategy()), RecommendResult::getGenerateStrategy, recommendResultDto.getGenerateStrategy())

                .eq(recommendResultDto.getOrganizationId() != null, RecommendResult::getOrganizationId, recommendResultDto.getOrganizationId())

                .eq(recommendResultDto.getCreateUser() != null, RecommendResult::getCreateUser, recommendResultDto.getCreateUser())

                .like(StrUtil.isNotBlank(recommendResultDto.getCreateUserName()), RecommendResult::getCreateUserName, recommendResultDto.getCreateUserName())

                .ge(recommendResultDto.getCreateTimeStart() != null, RecommendResult::getCreateTime, recommendResultDto.getCreateTimeStart())
                .le(recommendResultDto.getCreateTimeEnd() != null, RecommendResult::getCreateTime, recommendResultDto.getCreateTimeEnd())

                .eq(recommendResultDto.getUpdateUser() != null, RecommendResult::getUpdateUser, recommendResultDto.getUpdateUser())

                .like(StrUtil.isNotBlank(recommendResultDto.getUpdateUserName()), RecommendResult::getUpdateUserName, recommendResultDto.getUpdateUserName())

                .ge(recommendResultDto.getUpdateTimeStart() != null, RecommendResult::getUpdateTime, recommendResultDto.getUpdateTimeStart())
                .le(recommendResultDto.getUpdateTimeEnd() != null, RecommendResult::getUpdateTime, recommendResultDto.getUpdateTimeEnd())
        ;

        return wrapper;
    }
}
